package com.cskaoyan.javase.exception.handle2.catch2;

/**
 * @description: 多分支try...catch
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

import java.util.concurrent.ExecutionException;

/**
 * 如果代码只会发生一个异常，那么单分支的try...catch就够用了，那么如果发生多个异常呢？
 * 语法:
 * try {
 *  //可能出现异常的，正常的代码逻辑
 * } catch(要捕捉的异常对象1) {
 *  //每一个catch分支对应一个异常处理器
 *  //在catch分支中处理具体类型的代码异常
 * }catch(要捕捉的异常对象2) {
 *  //每一个catch分支对应一个异常处理器
 *  //在catch分支中处理具体类型的代码异常
 * }
 * 和if多分支很类似
 * 每个catch分支,有且只可能执行一个，如果上面的执行了，下面不可能再执行了
 *
 * 多分支try...catch的匹配流程
 * - 根据实际的异常对象的类型，和catch中声明的异常类型，从上到下一次做类型匹配
 * - 一旦通过类型匹配，发现实际异常对象的类型和catch中的异常对象类型匹配
 *   - 就把该异常对象交给这个catch分支进行处理（异常处理器）
 * - 没有相匹配catch代码块的异常，那么程序依然会自动向上抛出异常，直到JVM默认处理
 *
 *
 * > 多分支try...catch使用注意事项
 * - 多分支的异常处理的执行，有点类似于多分支if-else的执行，一次匹配，只会执行多个catch分支中的一个
 * - 如果多个catch中处理的是毫无关系的异常，那么catch的顺序并不需要特别注意
 * - 如果多个catch中处理的异常有父子关系，那么就必须要注意了
 *   - 如果父类异常写在了上面，那么子类异常的catch分支就永远没有机会执行了，并且会报错
 * - 所以，应该把具体子类放在catch分支的上面作类型匹配，父类放在后面作兜底
 * - catch()括号当中，尽量不要写Exception这种大而宽泛的异常
 *   - 而是应该写具体的异常，越具体越好
 *   - 这样对处理异常有帮助，能够清晰定位异常的类型
 *
 *   思考：
 *   单分支catch当中还可以一次性匹配多个异常。那么为什么还需要多分支catch
 *   多分支可以针对不同的异常 做出不同的处理
 *   而单分支就算能够同时匹配多个异常，也是一起处理 ，不能做不同处理
 *
 *
 */
public class Demo2 {
    public static void main(String[] args) {
        int[] arr = null;
        try {
            System.out.println(10 / 0); //除0异常
            System.out.println(arr.length);  //空指针异常
            arr = new int[]{1};
            System.out.println(arr[2]); //数组越界异常

        }
        catch (ArrayIndexOutOfBoundsException e) { //Exception 'java.lang.ArrayIndexOutOfBoundsException' has already been caught
            e.printStackTrace();
        } catch (ArithmeticException ae) {
            ae.printStackTrace();
            System.out.println("111111");
        } catch (NullPointerException npe) {
            npe.printStackTrace();
            System.out.println("2222222");
        }
        catch (Exception e){
            e.printStackTrace();
            System.out.println("我是永远的父类，我是永远的接盘侠 兜底的");
        }

        System.out.println("多分支catch之后");
    }
}
